home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume23 / flex2.3 / part07 < prev    next >
Encoding:
Internet Message Format  |  1990-10-10  |  54.0 KB

  1. Subject:  v23i043:  Flex, a fast lex replacement, Part07/10
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: 65a64ac9 c1ae906c 71a7080a eae9537b
  5.  
  6. Submitted-by: Vern Paxson <vern@cs.cornell.edu>
  7. Posting-number: Volume 23, Issue 43
  8. Archive-name: flex2.3/part07
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then feed it
  12. # into a shell via "sh file" or similar.  To overwrite existing files,
  13. # type "sh file -c".
  14. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  15. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  16. # Contents:  initscan.c.02 sym.c tblcmp.c
  17. # Wrapped by rsalz@litchi.bbn.com on Wed Oct 10 13:24:03 1990
  18. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  19. echo If this archive is complete, you will see the following message:
  20. echo '          "shar: End of archive 7 (of 10)."'
  21. if test -f 'initscan.c.02' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'initscan.c.02'\"
  23. else
  24.   echo shar: Extracting \"'initscan.c.02'\" \(18105 characters\)
  25.   sed "s/^X//" >'initscan.c.02' <<'END_OF_FILE'
  26. X*yy_cp = yy_hold_char; /* undo effects of setting up yytext */
  27. Xyy_c_buf_p = yy_cp = yy_bp + 1;
  28. XYY_DO_BEFORE_ACTION; /* set up yytext again */
  29. X# line 367 "scan.l"
  30. XBEGIN(CARETISBOL); return ( '>' );
  31. X    YY_BREAK
  32. Xcase 72:
  33. X# line 368 "scan.l"
  34. XRETURNNAME;
  35. X    YY_BREAK
  36. Xcase 73:
  37. X# line 369 "scan.l"
  38. Xsynerr( "bad start condition name" );
  39. X    YY_BREAK
  40. Xcase 74:
  41. X# line 371 "scan.l"
  42. XBEGIN(SECT2); return ( '^' );
  43. X    YY_BREAK
  44. Xcase 75:
  45. X# line 374 "scan.l"
  46. XRETURNCHAR;
  47. X    YY_BREAK
  48. Xcase 76:
  49. X# line 375 "scan.l"
  50. XBEGIN(SECT2); return ( '"' );
  51. X    YY_BREAK
  52. Xcase 77:
  53. X# line 377 "scan.l"
  54. X{
  55. X            synerr( "missing quote" );
  56. X            BEGIN(SECT2);
  57. X            ++linenum;
  58. X            return ( '"' );
  59. X            }
  60. X    YY_BREAK
  61. Xcase 78:
  62. X*yy_cp = yy_hold_char; /* undo effects of setting up yytext */
  63. Xyy_c_buf_p = yy_cp = yy_bp + 1;
  64. XYY_DO_BEFORE_ACTION; /* set up yytext again */
  65. X# line 385 "scan.l"
  66. XBEGIN(CCL); return ( '^' );
  67. X    YY_BREAK
  68. Xcase 79:
  69. X*yy_cp = yy_hold_char; /* undo effects of setting up yytext */
  70. Xyy_c_buf_p = yy_cp = yy_bp + 1;
  71. XYY_DO_BEFORE_ACTION; /* set up yytext again */
  72. X# line 386 "scan.l"
  73. Xreturn ( '^' );
  74. X    YY_BREAK
  75. Xcase 80:
  76. X# line 387 "scan.l"
  77. XBEGIN(CCL); yylval = '-'; return ( CHAR );
  78. X    YY_BREAK
  79. Xcase 81:
  80. X# line 388 "scan.l"
  81. XBEGIN(CCL); RETURNCHAR;
  82. X    YY_BREAK
  83. Xcase 82:
  84. X*yy_cp = yy_hold_char; /* undo effects of setting up yytext */
  85. Xyy_c_buf_p = yy_cp = yy_bp + 1;
  86. XYY_DO_BEFORE_ACTION; /* set up yytext again */
  87. X# line 390 "scan.l"
  88. Xreturn ( '-' );
  89. X    YY_BREAK
  90. Xcase 83:
  91. X# line 391 "scan.l"
  92. XRETURNCHAR;
  93. X    YY_BREAK
  94. Xcase 84:
  95. X# line 392 "scan.l"
  96. XBEGIN(SECT2); return ( ']' );
  97. X    YY_BREAK
  98. Xcase 85:
  99. X# line 395 "scan.l"
  100. X{
  101. X            yylval = myctoi( yytext );
  102. X            return ( NUMBER );
  103. X            }
  104. X    YY_BREAK
  105. Xcase 86:
  106. X# line 400 "scan.l"
  107. Xreturn ( ',' );
  108. X    YY_BREAK
  109. Xcase 87:
  110. X# line 401 "scan.l"
  111. XBEGIN(SECT2); return ( '}' );
  112. X    YY_BREAK
  113. Xcase 88:
  114. X# line 403 "scan.l"
  115. X{
  116. X            synerr( "bad character inside {}'s" );
  117. X            BEGIN(SECT2);
  118. X            return ( '}' );
  119. X            }
  120. X    YY_BREAK
  121. Xcase 89:
  122. X# line 409 "scan.l"
  123. X{
  124. X            synerr( "missing }" );
  125. X            BEGIN(SECT2);
  126. X            ++linenum;
  127. X            return ( '}' );
  128. X            }
  129. X    YY_BREAK
  130. Xcase 90:
  131. X# line 417 "scan.l"
  132. Xsynerr( "bad name in {}'s" ); BEGIN(SECT2);
  133. X    YY_BREAK
  134. Xcase 91:
  135. X# line 418 "scan.l"
  136. Xsynerr( "missing }" ); ++linenum; BEGIN(SECT2);
  137. X    YY_BREAK
  138. Xcase 92:
  139. X# line 421 "scan.l"
  140. Xbracelevel = 0;
  141. X    YY_BREAK
  142. Xcase 93:
  143. X# line 422 "scan.l"
  144. X{
  145. X            ACTION_ECHO;
  146. X            CHECK_REJECT(yytext);
  147. X            }
  148. X    YY_BREAK
  149. Xcase 94:
  150. X# line 426 "scan.l"
  151. X{
  152. X            ACTION_ECHO;
  153. X            CHECK_YYMORE(yytext);
  154. X            }
  155. X    YY_BREAK
  156. Xcase 95:
  157. X# line 430 "scan.l"
  158. XACTION_ECHO;
  159. X    YY_BREAK
  160. Xcase 96:
  161. X# line 431 "scan.l"
  162. X{
  163. X            ++linenum;
  164. X            ACTION_ECHO;
  165. X            if ( bracelevel == 0 ||
  166. X                 (doing_codeblock && indented_code) )
  167. X                {
  168. X                if ( ! doing_codeblock )
  169. X                fputs( "\tYY_BREAK\n", temp_action_file );
  170. X                
  171. X                doing_codeblock = false;
  172. X                BEGIN(SECT2);
  173. X                }
  174. X            }
  175. X    YY_BREAK
  176. X    /* Reject and YYmore() are checked for above, in PERCENT_BRACE_ACTION */
  177. Xcase 97:
  178. X# line 447 "scan.l"
  179. XACTION_ECHO; ++bracelevel;
  180. X    YY_BREAK
  181. Xcase 98:
  182. X# line 448 "scan.l"
  183. XACTION_ECHO; --bracelevel;
  184. X    YY_BREAK
  185. Xcase 99:
  186. X# line 449 "scan.l"
  187. XACTION_ECHO;
  188. X    YY_BREAK
  189. Xcase 100:
  190. X# line 450 "scan.l"
  191. XACTION_ECHO;
  192. X    YY_BREAK
  193. Xcase 101:
  194. X# line 451 "scan.l"
  195. XACTION_ECHO; BEGIN(ACTION_COMMENT);
  196. X    YY_BREAK
  197. Xcase 102:
  198. X# line 452 "scan.l"
  199. XACTION_ECHO; /* character constant */
  200. X    YY_BREAK
  201. Xcase 103:
  202. X# line 453 "scan.l"
  203. XACTION_ECHO; BEGIN(ACTION_STRING);
  204. X    YY_BREAK
  205. Xcase 104:
  206. X# line 454 "scan.l"
  207. X{
  208. X            ++linenum;
  209. X            ACTION_ECHO;
  210. X            if ( bracelevel == 0 )
  211. X                {
  212. X                fputs( "\tYY_BREAK\n", temp_action_file );
  213. X                BEGIN(SECT2);
  214. X                }
  215. X            }
  216. X    YY_BREAK
  217. Xcase 105:
  218. X# line 463 "scan.l"
  219. XACTION_ECHO;
  220. X    YY_BREAK
  221. Xcase 106:
  222. X# line 465 "scan.l"
  223. XACTION_ECHO; BEGIN(ACTION);
  224. X    YY_BREAK
  225. Xcase 107:
  226. X# line 466 "scan.l"
  227. XACTION_ECHO;
  228. X    YY_BREAK
  229. Xcase 108:
  230. X# line 467 "scan.l"
  231. XACTION_ECHO;
  232. X    YY_BREAK
  233. Xcase 109:
  234. X# line 468 "scan.l"
  235. X++linenum; ACTION_ECHO;
  236. X    YY_BREAK
  237. Xcase 110:
  238. X# line 469 "scan.l"
  239. XACTION_ECHO;
  240. X    YY_BREAK
  241. Xcase 111:
  242. X# line 471 "scan.l"
  243. XACTION_ECHO;
  244. X    YY_BREAK
  245. Xcase 112:
  246. X# line 472 "scan.l"
  247. XACTION_ECHO;
  248. X    YY_BREAK
  249. Xcase 113:
  250. X# line 473 "scan.l"
  251. X++linenum; ACTION_ECHO;
  252. X    YY_BREAK
  253. Xcase 114:
  254. X# line 474 "scan.l"
  255. XACTION_ECHO; BEGIN(ACTION);
  256. X    YY_BREAK
  257. Xcase 115:
  258. X# line 475 "scan.l"
  259. XACTION_ECHO;
  260. X    YY_BREAK
  261. Xcase YY_STATE_EOF(ACTION):
  262. Xcase YY_STATE_EOF(ACTION_COMMENT):
  263. Xcase YY_STATE_EOF(ACTION_STRING):
  264. X# line 477 "scan.l"
  265. X{
  266. X            synerr( "EOF encountered inside an action" );
  267. X            yyterminate();
  268. X            }
  269. X    YY_BREAK
  270. Xcase 117:
  271. X# line 483 "scan.l"
  272. X{
  273. X            yylval = myesc( yytext );
  274. X            return ( CHAR );
  275. X            }
  276. X    YY_BREAK
  277. Xcase 118:
  278. X# line 488 "scan.l"
  279. X{
  280. X            yylval = myesc( yytext );
  281. X            BEGIN(CCL);
  282. X            return ( CHAR );
  283. X            }
  284. X    YY_BREAK
  285. Xcase 119:
  286. X# line 495 "scan.l"
  287. XECHO;
  288. X    YY_BREAK
  289. Xcase 120:
  290. X# line 496 "scan.l"
  291. XYY_FATAL_ERROR( "flex scanner jammed" );
  292. X    YY_BREAK
  293. Xcase YY_STATE_EOF(INITIAL):
  294. Xcase YY_STATE_EOF(SECT2):
  295. Xcase YY_STATE_EOF(SECT3):
  296. Xcase YY_STATE_EOF(CODEBLOCK):
  297. Xcase YY_STATE_EOF(PICKUPDEF):
  298. Xcase YY_STATE_EOF(SC):
  299. Xcase YY_STATE_EOF(CARETISBOL):
  300. Xcase YY_STATE_EOF(NUM):
  301. Xcase YY_STATE_EOF(QUOTE):
  302. Xcase YY_STATE_EOF(FIRSTCCL):
  303. Xcase YY_STATE_EOF(CCL):
  304. Xcase YY_STATE_EOF(RECOVER):
  305. Xcase YY_STATE_EOF(BRACEERROR):
  306. Xcase YY_STATE_EOF(C_COMMENT):
  307. Xcase YY_STATE_EOF(PERCENT_BRACE_ACTION):
  308. Xcase YY_STATE_EOF(USED_LIST):
  309. Xcase YY_STATE_EOF(CODEBLOCK_2):
  310. Xcase YY_STATE_EOF(XLATION):
  311. X    yyterminate();
  312. X
  313. X        case YY_END_OF_BUFFER:
  314. X        {
  315. X        /* amount of text matched not including the EOB char */
  316. X        int yy_amount_of_matched_text = yy_cp - yytext - 1;
  317. X
  318. X        /* undo the effects of YY_DO_BEFORE_ACTION */
  319. X        *yy_cp = yy_hold_char;
  320. X
  321. X        /* note that here we test for yy_c_buf_p "<=" to the position
  322. X         * of the first EOB in the buffer, since yy_c_buf_p will
  323. X         * already have been incremented past the NUL character
  324. X         * (since all states make transitions on EOB to the end-
  325. X         * of-buffer state).  Contrast this with the test in yyinput().
  326. X         */
  327. X        if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
  328. X            /* this was really a NUL */
  329. X            {
  330. X            yy_state_type yy_next_state;
  331. X
  332. X            yy_c_buf_p = yytext + yy_amount_of_matched_text;
  333. X
  334. X            yy_current_state = yy_get_previous_state();
  335. X
  336. X            /* okay, we're now positioned to make the
  337. X             * NUL transition.  We couldn't have
  338. X             * yy_get_previous_state() go ahead and do it
  339. X             * for us because it doesn't know how to deal
  340. X             * with the possibility of jamming (and we
  341. X             * don't want to build jamming into it because
  342. X             * then it will run more slowly)
  343. X             */
  344. X
  345. X            yy_next_state = yy_try_NUL_trans( yy_current_state );
  346. X
  347. X            yy_bp = yytext + YY_MORE_ADJ;
  348. X
  349. X            if ( yy_next_state )
  350. X            {
  351. X            /* consume the NUL */
  352. X            yy_cp = ++yy_c_buf_p;
  353. X            yy_current_state = yy_next_state;
  354. X            goto yy_match;
  355. X            }
  356. X
  357. X            else
  358. X            {
  359. X                yy_cp = yy_last_accepting_cpos;
  360. X                yy_current_state = yy_last_accepting_state;
  361. X            goto yy_find_action;
  362. X            }
  363. X            }
  364. X
  365. X        else switch ( yy_get_next_buffer() )
  366. X            {
  367. X            case EOB_ACT_END_OF_FILE:
  368. X            {
  369. X            yy_did_buffer_switch_on_eof = 0;
  370. X
  371. X            if ( yywrap() )
  372. X                {
  373. X                /* note: because we've taken care in
  374. X                 * yy_get_next_buffer() to have set up yytext,
  375. X                 * we can now set up yy_c_buf_p so that if some
  376. X                 * total hoser (like flex itself) wants
  377. X                 * to call the scanner after we return the
  378. X                 * YY_NULL, it'll still work - another YY_NULL
  379. X                 * will get returned.
  380. X                 */
  381. X                yy_c_buf_p = yytext + YY_MORE_ADJ;
  382. X
  383. X                yy_act = YY_STATE_EOF((yy_start - 1) / 2);
  384. X                goto do_action;
  385. X                }
  386. X
  387. X            else
  388. X                {
  389. X                if ( ! yy_did_buffer_switch_on_eof )
  390. X                YY_NEW_FILE;
  391. X                }
  392. X            }
  393. X            break;
  394. X
  395. X            case EOB_ACT_CONTINUE_SCAN:
  396. X            yy_c_buf_p = yytext + yy_amount_of_matched_text;
  397. X
  398. X            yy_current_state = yy_get_previous_state();
  399. X
  400. X            yy_cp = yy_c_buf_p;
  401. X            yy_bp = yytext + YY_MORE_ADJ;
  402. X            goto yy_match;
  403. X
  404. X            case EOB_ACT_LAST_MATCH:
  405. X            yy_c_buf_p =
  406. X                &yy_current_buffer->yy_ch_buf[yy_n_chars];
  407. X
  408. X            yy_current_state = yy_get_previous_state();
  409. X
  410. X            yy_cp = yy_c_buf_p;
  411. X            yy_bp = yytext + YY_MORE_ADJ;
  412. X            goto yy_find_action;
  413. X            }
  414. X        break;
  415. X        }
  416. X
  417. X        default:
  418. X#ifdef FLEX_DEBUG
  419. X        printf( "action # %d\n", yy_act );
  420. X#endif
  421. X        YY_FATAL_ERROR(
  422. X            "fatal flex scanner internal error--no action found" );
  423. X        }
  424. X    }
  425. X    }
  426. X
  427. X
  428. X/* yy_get_next_buffer - try to read in a new buffer
  429. X *
  430. X * synopsis
  431. X *     int yy_get_next_buffer();
  432. X *     
  433. X * returns a code representing an action
  434. X *     EOB_ACT_LAST_MATCH - 
  435. X *     EOB_ACT_CONTINUE_SCAN - continue scanning from current position
  436. X *     EOB_ACT_END_OF_FILE - end of file
  437. X */
  438. X
  439. Xstatic int yy_get_next_buffer()
  440. X
  441. X    {
  442. X    register YY_CHAR *dest = yy_current_buffer->yy_ch_buf;
  443. X    register YY_CHAR *source = yytext - 1; /* copy prev. char, too */
  444. X    register int number_to_move, i;
  445. X    int ret_val;
  446. X
  447. X    if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
  448. X    YY_FATAL_ERROR(
  449. X        "fatal flex scanner internal error--end of buffer missed" );
  450. X
  451. X    /* try to read more data */
  452. X
  453. X    /* first move last chars to start of buffer */
  454. X    number_to_move = yy_c_buf_p - yytext;
  455. X
  456. X    for ( i = 0; i < number_to_move; ++i )
  457. X    *(dest++) = *(source++);
  458. X
  459. X    if ( yy_current_buffer->yy_eof_status != EOF_NOT_SEEN )
  460. X    /* don't do the read, it's not guaranteed to return an EOF,
  461. X     * just force an EOF
  462. X     */
  463. X    yy_n_chars = 0;
  464. X
  465. X    else
  466. X    {
  467. X    int num_to_read = yy_current_buffer->yy_buf_size - number_to_move - 1;
  468. X
  469. X    if ( num_to_read > YY_READ_BUF_SIZE )
  470. X        num_to_read = YY_READ_BUF_SIZE;
  471. X
  472. X    else if ( num_to_read <= 0 )
  473. X        YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" );
  474. X
  475. X    /* read in more data */
  476. X    YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
  477. X          yy_n_chars, num_to_read );
  478. X    }
  479. X
  480. X    if ( yy_n_chars == 0 )
  481. X    {
  482. X    if ( number_to_move == 1 )
  483. X        {
  484. X        ret_val = EOB_ACT_END_OF_FILE;
  485. X        yy_current_buffer->yy_eof_status = EOF_DONE;
  486. X        }
  487. X
  488. X    else
  489. X        {
  490. X        ret_val = EOB_ACT_LAST_MATCH;
  491. X        yy_current_buffer->yy_eof_status = EOF_PENDING;
  492. X        }
  493. X    }
  494. X
  495. X    else
  496. X    ret_val = EOB_ACT_CONTINUE_SCAN;
  497. X
  498. X    yy_n_chars += number_to_move;
  499. X    yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
  500. X    yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
  501. X
  502. X    /* yytext begins at the second character in yy_ch_buf; the first
  503. X     * character is the one which preceded it before reading in the latest
  504. X     * buffer; it needs to be kept around in case it's a newline, so
  505. X     * yy_get_previous_state() will have with '^' rules active
  506. X     */
  507. X
  508. X    yytext = &yy_current_buffer->yy_ch_buf[1];
  509. X
  510. X    return ( ret_val );
  511. X    }
  512. X
  513. X
  514. X/* yy_get_previous_state - get the state just before the EOB char was reached
  515. X *
  516. X * synopsis
  517. X *     yy_state_type yy_get_previous_state();
  518. X */
  519. X
  520. Xstatic yy_state_type yy_get_previous_state()
  521. X
  522. X    {
  523. X    register yy_state_type yy_current_state;
  524. X    register YY_CHAR *yy_cp;
  525. X
  526. X    register YY_CHAR *yy_bp = yytext;
  527. X
  528. X    yy_current_state = yy_start;
  529. X    if ( yy_bp[-1] == '\n' )
  530. X    ++yy_current_state;
  531. X
  532. X    for ( yy_cp = yytext + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
  533. X    {
  534. X    register YY_CHAR yy_c = (*yy_cp ? yy_ec[*yy_cp] : 1);
  535. X    if ( yy_accept[yy_current_state] )
  536. X        {
  537. X        yy_last_accepting_state = yy_current_state;
  538. X        yy_last_accepting_cpos = yy_cp;
  539. X        }
  540. X    while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
  541. X        {
  542. X        yy_current_state = yy_def[yy_current_state];
  543. X        if ( yy_current_state >= 341 )
  544. X        yy_c = yy_meta[yy_c];
  545. X        }
  546. X    yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
  547. X    }
  548. X
  549. X    return ( yy_current_state );
  550. X    }
  551. X
  552. X
  553. X/* yy_try_NUL_trans - try to make a transition on the NUL character
  554. X *
  555. X * synopsis
  556. X *     next_state = yy_try_NUL_trans( current_state );
  557. X */
  558. X
  559. X#ifdef YY_USE_PROTOS
  560. Xstatic yy_state_type yy_try_NUL_trans( register yy_state_type yy_current_state )
  561. X#else
  562. Xstatic yy_state_type yy_try_NUL_trans( yy_current_state )
  563. Xregister yy_state_type yy_current_state;
  564. X#endif
  565. X
  566. X    {
  567. X    register int yy_is_jam;
  568. X    register YY_CHAR *yy_cp = yy_c_buf_p;
  569. X
  570. X    register YY_CHAR yy_c = 1;
  571. X    if ( yy_accept[yy_current_state] )
  572. X    {
  573. X    yy_last_accepting_state = yy_current_state;
  574. X    yy_last_accepting_cpos = yy_cp;
  575. X    }
  576. X    while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
  577. X    {
  578. X    yy_current_state = yy_def[yy_current_state];
  579. X    if ( yy_current_state >= 341 )
  580. X        yy_c = yy_meta[yy_c];
  581. X    }
  582. X    yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
  583. X    yy_is_jam = (yy_current_state == 340);
  584. X
  585. X    return ( yy_is_jam ? 0 : yy_current_state );
  586. X    }
  587. X
  588. X
  589. X#ifdef YY_USE_PROTOS
  590. Xstatic void yyunput( YY_CHAR c, register YY_CHAR *yy_bp )
  591. X#else
  592. Xstatic void yyunput( c, yy_bp )
  593. XYY_CHAR c;
  594. Xregister YY_CHAR *yy_bp;
  595. X#endif
  596. X
  597. X    {
  598. X    register YY_CHAR *yy_cp = yy_c_buf_p;
  599. X
  600. X    /* undo effects of setting up yytext */
  601. X    *yy_cp = yy_hold_char;
  602. X
  603. X    if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
  604. X    { /* need to shift things up to make room */
  605. X    register int number_to_move = yy_n_chars + 2; /* +2 for EOB chars */
  606. X    register YY_CHAR *dest =
  607. X        &yy_current_buffer->yy_ch_buf[yy_current_buffer->yy_buf_size + 2];
  608. X    register YY_CHAR *source =
  609. X        &yy_current_buffer->yy_ch_buf[number_to_move];
  610. X
  611. X    while ( source > yy_current_buffer->yy_ch_buf )
  612. X        *--dest = *--source;
  613. X
  614. X    yy_cp += dest - source;
  615. X    yy_bp += dest - source;
  616. X    yy_n_chars = yy_current_buffer->yy_buf_size;
  617. X
  618. X    if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
  619. X        YY_FATAL_ERROR( "flex scanner push-back overflow" );
  620. X    }
  621. X
  622. X    if ( yy_cp > yy_bp && yy_cp[-1] == '\n' )
  623. X    yy_cp[-2] = '\n';
  624. X
  625. X    *--yy_cp = c;
  626. X
  627. X    /* note: the formal parameter *must* be called "yy_bp" for this
  628. X     *       macro to now work correctly
  629. X     */
  630. X    YY_DO_BEFORE_ACTION; /* set up yytext again */
  631. X    }
  632. X
  633. X
  634. X#ifdef __cplusplus
  635. Xstatic int yyinput()
  636. X#else
  637. Xstatic int input()
  638. X#endif
  639. X
  640. X    {
  641. X    int c;
  642. X    YY_CHAR *yy_cp = yy_c_buf_p;
  643. X
  644. X    *yy_cp = yy_hold_char;
  645. X
  646. X    if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
  647. X    {
  648. X    /* yy_c_buf_p now points to the character we want to return.
  649. X     * If this occurs *before* the EOB characters, then it's a
  650. X     * valid NUL; if not, then we've hit the end of the buffer.
  651. X     */
  652. X    if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
  653. X        /* this was really a NUL */
  654. X        *yy_c_buf_p = '\0';
  655. X
  656. X    else
  657. X        { /* need more input */
  658. X        yytext = yy_c_buf_p;
  659. X        ++yy_c_buf_p;
  660. X
  661. X        switch ( yy_get_next_buffer() )
  662. X        {
  663. X        case EOB_ACT_END_OF_FILE:
  664. X            {
  665. X            if ( yywrap() )
  666. X            {
  667. X            yy_c_buf_p = yytext + YY_MORE_ADJ;
  668. X            return ( EOF );
  669. X            }
  670. X
  671. X            YY_NEW_FILE;
  672. X
  673. X#ifdef __cplusplus
  674. X            return ( yyinput() );
  675. X#else
  676. X            return ( input() );
  677. X#endif
  678. X            }
  679. X            break;
  680. X
  681. X        case EOB_ACT_CONTINUE_SCAN:
  682. X            yy_c_buf_p = yytext + YY_MORE_ADJ;
  683. X            break;
  684. X
  685. X        case EOB_ACT_LAST_MATCH:
  686. X#ifdef __cplusplus
  687. X            YY_FATAL_ERROR( "unexpected last match in yyinput()" );
  688. X#else
  689. X            YY_FATAL_ERROR( "unexpected last match in input()" );
  690. X#endif
  691. X        }
  692. X        }
  693. X    }
  694. X
  695. X    c = *yy_c_buf_p;
  696. X    yy_hold_char = *++yy_c_buf_p;
  697. X
  698. X    return ( c );
  699. X    }
  700. X
  701. X
  702. X#ifdef YY_USE_PROTOS
  703. Xvoid yyrestart( FILE *input_file )
  704. X#else
  705. Xvoid yyrestart( input_file )
  706. XFILE *input_file;
  707. X#endif
  708. X
  709. X    {
  710. X    yy_init_buffer( yy_current_buffer, input_file );
  711. X    yy_load_buffer_state();
  712. X    }
  713. X
  714. X
  715. X#ifdef YY_USE_PROTOS
  716. Xvoid yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
  717. X#else
  718. Xvoid yy_switch_to_buffer( new_buffer )
  719. XYY_BUFFER_STATE new_buffer;
  720. X#endif
  721. X
  722. X    {
  723. X    if ( yy_current_buffer == new_buffer )
  724. X    return;
  725. X
  726. X    if ( yy_current_buffer )
  727. X    {
  728. X    /* flush out information for old buffer */
  729. X    *yy_c_buf_p = yy_hold_char;
  730. X    yy_current_buffer->yy_buf_pos = yy_c_buf_p;
  731. X    yy_current_buffer->yy_n_chars = yy_n_chars;
  732. X    }
  733. X
  734. X    yy_current_buffer = new_buffer;
  735. X    yy_load_buffer_state();
  736. X
  737. X    /* we don't actually know whether we did this switch during
  738. X     * EOF (yywrap()) processing, but the only time this flag
  739. X     * is looked at is after yywrap() is called, so it's safe
  740. X     * to go ahead and always set it.
  741. X     */
  742. X    yy_did_buffer_switch_on_eof = 1;
  743. X    }
  744. X
  745. X
  746. X#ifdef YY_USE_PROTOS
  747. Xvoid yy_load_buffer_state( void )
  748. X#else
  749. Xvoid yy_load_buffer_state()
  750. X#endif
  751. X
  752. X    {
  753. X    yy_n_chars = yy_current_buffer->yy_n_chars;
  754. X    yytext = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
  755. X    yyin = yy_current_buffer->yy_input_file;
  756. X    yy_hold_char = *yy_c_buf_p;
  757. X    }
  758. X
  759. X
  760. X#ifdef YY_USE_PROTOS
  761. XYY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
  762. X#else
  763. XYY_BUFFER_STATE yy_create_buffer( file, size )
  764. XFILE *file;
  765. Xint size;
  766. X#endif
  767. X
  768. X    {
  769. X    YY_BUFFER_STATE b;
  770. X
  771. X    b = (YY_BUFFER_STATE) malloc( sizeof( struct yy_buffer_state ) );
  772. X
  773. X    if ( ! b )
  774. X    YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
  775. X
  776. X    b->yy_buf_size = size;
  777. X
  778. X    /* yy_ch_buf has to be 2 characters longer than the size given because
  779. X     * we need to put in 2 end-of-buffer characters.
  780. X     */
  781. X    b->yy_ch_buf = (YY_CHAR *) malloc( (unsigned) (b->yy_buf_size + 2) );
  782. X
  783. X    if ( ! b->yy_ch_buf )
  784. X    YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
  785. X
  786. X    yy_init_buffer( b, file );
  787. X
  788. X    return ( b );
  789. X    }
  790. X
  791. X
  792. X#ifdef YY_USE_PROTOS
  793. Xvoid yy_delete_buffer( YY_BUFFER_STATE b )
  794. X#else
  795. Xvoid yy_delete_buffer( b )
  796. XYY_BUFFER_STATE b;
  797. X#endif
  798. X
  799. X    {
  800. X    if ( b == yy_current_buffer )
  801. X    yy_current_buffer = (YY_BUFFER_STATE) 0;
  802. X
  803. X    free( (char *) b->yy_ch_buf );
  804. X    free( (char *) b );
  805. X    }
  806. X
  807. X
  808. X#ifdef YY_USE_PROTOS
  809. Xvoid yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
  810. X#else
  811. Xvoid yy_init_buffer( b, file )
  812. XYY_BUFFER_STATE b;
  813. XFILE *file;
  814. X#endif
  815. X
  816. X    {
  817. X    b->yy_input_file = file;
  818. X
  819. X    /* we put in the '\n' and start reading from [1] so that an
  820. X     * initial match-at-newline will be true.
  821. X     */
  822. X
  823. X    b->yy_ch_buf[0] = '\n';
  824. X    b->yy_n_chars = 1;
  825. X
  826. X    /* we always need two end-of-buffer characters.  The first causes
  827. X     * a transition to the end-of-buffer state.  The second causes
  828. X     * a jam in that state.
  829. X     */
  830. X    b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
  831. X    b->yy_ch_buf[2] = YY_END_OF_BUFFER_CHAR;
  832. X
  833. X    b->yy_buf_pos = &b->yy_ch_buf[1];
  834. X
  835. X    b->yy_eof_status = EOF_NOT_SEEN;
  836. X    }
  837. X# line 496 "scan.l"
  838. X
  839. X
  840. X
  841. Xint yywrap()
  842. X
  843. X    {
  844. X    if ( --num_input_files > 0 )
  845. X    {
  846. X    set_input_file( *++input_files );
  847. X    return ( 0 );
  848. X    }
  849. X
  850. X    else
  851. X    return ( 1 );
  852. X    }
  853. X
  854. X
  855. X/* set_input_file - open the given file (if NULL, stdin) for scanning */
  856. X
  857. Xvoid set_input_file( file )
  858. Xchar *file;
  859. X
  860. X    {
  861. X    if ( file )
  862. X    {
  863. X    infilename = file;
  864. X    yyin = fopen( infilename, "r" );
  865. X
  866. X    if ( yyin == NULL )
  867. X        lerrsf( "can't open %s", file );
  868. X    }
  869. X
  870. X    else
  871. X    {
  872. X    yyin = stdin;
  873. X    infilename = "<stdin>";
  874. X    }
  875. X    }
  876. END_OF_FILE
  877.   if test 18105 -ne `wc -c <'initscan.c.02'`; then
  878.     echo shar: \"'initscan.c.02'\" unpacked with wrong size!
  879.   fi
  880.   # end of 'initscan.c.02'
  881. fi
  882. if test -f 'sym.c' -a "${1}" != "-c" ; then 
  883.   echo shar: Will not clobber existing file \"'sym.c'\"
  884. else
  885.   echo shar: Extracting \"'sym.c'\" \(7527 characters\)
  886.   sed "s/^X//" >'sym.c' <<'END_OF_FILE'
  887. X/* sym - symbol table routines */
  888. X
  889. X/*-
  890. X * Copyright (c) 1990 The Regents of the University of California.
  891. X * All rights reserved.
  892. X *
  893. X * This code is derived from software contributed to Berkeley by
  894. X * Vern Paxson.
  895. X * 
  896. X * The United States Government has rights in this work pursuant
  897. X * to contract no. DE-AC03-76SF00098 between the United States
  898. X * Department of Energy and the University of California.
  899. X *
  900. X * Redistribution and use in source and binary forms are permitted provided
  901. X * that: (1) source distributions retain this entire copyright notice and
  902. X * comment, and (2) distributions including binaries display the following
  903. X * acknowledgement:  ``This product includes software developed by the
  904. X * University of California, Berkeley and its contributors'' in the
  905. X * documentation or other materials provided with the distribution and in
  906. X * all advertising materials mentioning features or use of this software.
  907. X * Neither the name of the University nor the names of its contributors may
  908. X * be used to endorse or promote products derived from this software without
  909. X * specific prior written permission.
  910. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  911. X * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  912. X * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  913. X */
  914. X
  915. X#ifndef lint
  916. Xstatic char rcsid[] =
  917. X    "@(#) $Header: /usr/fsys/odin/a/vern/flex/RCS/sym.c,v 2.4 90/06/27 23:48:36 vern Exp $ (LBL)";
  918. X#endif
  919. X
  920. X#include "flexdef.h"
  921. X
  922. X
  923. X/* declare functions that have forward references */
  924. X
  925. Xint hashfunct PROTO((register char[], int));
  926. X
  927. X
  928. Xstruct hash_entry *ndtbl[NAME_TABLE_HASH_SIZE];
  929. Xstruct hash_entry *sctbl[START_COND_HASH_SIZE];
  930. Xstruct hash_entry *ccltab[CCL_HASH_SIZE];
  931. X
  932. Xstruct hash_entry *findsym();
  933. X
  934. X
  935. X/* addsym - add symbol and definitions to symbol table
  936. X *
  937. X * synopsis
  938. X *    char sym[], *str_def;
  939. X *    int int_def;
  940. X *    hash_table table;
  941. X *    int table_size;
  942. X *    0 / -1 = addsym( sym, def, int_def, table, table_size );
  943. X *
  944. X * -1 is returned if the symbol already exists, and the change not made.
  945. X */
  946. X
  947. Xint addsym( sym, str_def, int_def, table, table_size )
  948. Xregister char sym[];
  949. Xchar *str_def;
  950. Xint int_def;
  951. Xhash_table table;
  952. Xint table_size;
  953. X
  954. X    {
  955. X    int hash_val = hashfunct( sym, table_size );
  956. X    register struct hash_entry *sym_entry = table[hash_val];
  957. X    register struct hash_entry *new_entry;
  958. X    register struct hash_entry *successor;
  959. X
  960. X    while ( sym_entry )
  961. X    {
  962. X    if ( ! strcmp( sym, sym_entry->name ) )
  963. X        { /* entry already exists */
  964. X        return ( -1 );
  965. X        }
  966. X    
  967. X    sym_entry = sym_entry->next;
  968. X    }
  969. X
  970. X    /* create new entry */
  971. X    new_entry = (struct hash_entry *) malloc( sizeof( struct hash_entry ) );
  972. X
  973. X    if ( new_entry == NULL )
  974. X    flexfatal( "symbol table memory allocation failed" );
  975. X
  976. X    if ( (successor = table[hash_val]) )
  977. X    {
  978. X    new_entry->next = successor;
  979. X    successor->prev = new_entry;
  980. X    }
  981. X    else
  982. X    new_entry->next = NULL;
  983. X
  984. X    new_entry->prev = NULL;
  985. X    new_entry->name = sym;
  986. X    new_entry->str_val = str_def;
  987. X    new_entry->int_val = int_def;
  988. X
  989. X    table[hash_val] = new_entry;
  990. X
  991. X    return ( 0 );
  992. X    }
  993. X
  994. X
  995. X/* cclinstal - save the text of a character class
  996. X *
  997. X * synopsis
  998. X *    Char ccltxt[];
  999. X *    int cclnum;
  1000. X *    cclinstal( ccltxt, cclnum );
  1001. X */
  1002. X
  1003. Xvoid cclinstal( ccltxt, cclnum )
  1004. XChar ccltxt[];
  1005. Xint cclnum;
  1006. X
  1007. X    {
  1008. X    /* we don't bother checking the return status because we are not called
  1009. X     * unless the symbol is new
  1010. X     */
  1011. X    Char *copy_unsigned_string();
  1012. X
  1013. X    (void) addsym( (char *) copy_unsigned_string( ccltxt ), (char *) 0, cclnum,
  1014. X           ccltab, CCL_HASH_SIZE );
  1015. X    }
  1016. X
  1017. X
  1018. X/* ccllookup - lookup the number associated with character class text
  1019. X *
  1020. X * synopsis
  1021. X *    Char ccltxt[];
  1022. X *    int ccllookup, cclval;
  1023. X *    cclval/0 = ccllookup( ccltxt );
  1024. X */
  1025. X
  1026. Xint ccllookup( ccltxt )
  1027. XChar ccltxt[];
  1028. X
  1029. X    {
  1030. X    return ( findsym( (char *) ccltxt, ccltab, CCL_HASH_SIZE )->int_val );
  1031. X    }
  1032. X
  1033. X
  1034. X/* findsym - find symbol in symbol table
  1035. X *
  1036. X * synopsis
  1037. X *    char sym[];
  1038. X *    hash_table table;
  1039. X *    int table_size;
  1040. X *    struct hash_entry *sym_entry, *findsym();
  1041. X *    sym_entry = findsym( sym, table, table_size );
  1042. X */
  1043. X
  1044. Xstruct hash_entry *findsym( sym, table, table_size )
  1045. Xregister char sym[];
  1046. Xhash_table table;
  1047. Xint table_size;
  1048. X
  1049. X    {
  1050. X    register struct hash_entry *sym_entry = table[hashfunct( sym, table_size )];
  1051. X    static struct hash_entry empty_entry =
  1052. X    {
  1053. X    (struct hash_entry *) 0, (struct hash_entry *) 0, NULL, NULL, 0,
  1054. X    } ;
  1055. X
  1056. X    while ( sym_entry )
  1057. X    {
  1058. X    if ( ! strcmp( sym, sym_entry->name ) )
  1059. X        return ( sym_entry );
  1060. X    sym_entry = sym_entry->next;
  1061. X    }
  1062. X
  1063. X    return ( &empty_entry );
  1064. X    }
  1065. X
  1066. X    
  1067. X/* hashfunct - compute the hash value for "str" and hash size "hash_size"
  1068. X *
  1069. X * synopsis
  1070. X *    char str[];
  1071. X *    int hash_size, hash_val;
  1072. X *    hash_val = hashfunct( str, hash_size );
  1073. X */
  1074. X
  1075. Xint hashfunct( str, hash_size )
  1076. Xregister char str[];
  1077. Xint hash_size;
  1078. X
  1079. X    {
  1080. X    register int hashval;
  1081. X    register int locstr;
  1082. X
  1083. X    hashval = 0;
  1084. X    locstr = 0;
  1085. X
  1086. X    while ( str[locstr] )
  1087. X    hashval = ((hashval << 1) + str[locstr++]) % hash_size;
  1088. X
  1089. X    return ( hashval );
  1090. X    }
  1091. X
  1092. X
  1093. X/* ndinstal - install a name definition
  1094. X *
  1095. X * synopsis
  1096. X *    char nd[];
  1097. X *    Char def[];
  1098. X *    ndinstal( nd, def );
  1099. X */
  1100. X
  1101. Xvoid ndinstal( nd, def )
  1102. Xchar nd[];
  1103. XChar def[];
  1104. X
  1105. X    {
  1106. X    char *copy_string();
  1107. X    Char *copy_unsigned_string();
  1108. X
  1109. X    if ( addsym( copy_string( nd ), (char *) copy_unsigned_string( def ), 0,
  1110. X         ndtbl, NAME_TABLE_HASH_SIZE ) )
  1111. X    synerr( "name defined twice" );
  1112. X    }
  1113. X
  1114. X
  1115. X/* ndlookup - lookup a name definition
  1116. X *
  1117. X * synopsis
  1118. X *    char nd[], *def;
  1119. X *    char *ndlookup();
  1120. X *    def/NULL = ndlookup( nd );
  1121. X */
  1122. X
  1123. XChar *ndlookup( nd )
  1124. Xchar nd[];
  1125. X
  1126. X    {
  1127. X    return ( (Char *) findsym( nd, ndtbl, NAME_TABLE_HASH_SIZE )->str_val );
  1128. X    }
  1129. X
  1130. X
  1131. X/* scinstal - make a start condition
  1132. X *
  1133. X * synopsis
  1134. X *    char str[];
  1135. X *    int xcluflg;
  1136. X *    scinstal( str, xcluflg );
  1137. X *
  1138. X * NOTE
  1139. X *    the start condition is Exclusive if xcluflg is true
  1140. X */
  1141. X
  1142. Xvoid scinstal( str, xcluflg )
  1143. Xchar str[];
  1144. Xint xcluflg;
  1145. X
  1146. X    {
  1147. X    char *copy_string();
  1148. X
  1149. X    /* bit of a hack.  We know how the default start-condition is
  1150. X     * declared, and don't put out a define for it, because it
  1151. X     * would come out as "#define 0 1"
  1152. X     */
  1153. X    /* actually, this is no longer the case.  The default start-condition
  1154. X     * is now called "INITIAL".  But we keep the following for the sake
  1155. X     * of future robustness.
  1156. X     */
  1157. X
  1158. X    if ( strcmp( str, "0" ) )
  1159. X    printf( "#define %s %d\n", str, lastsc );
  1160. X
  1161. X    if ( ++lastsc >= current_max_scs )
  1162. X    {
  1163. X    current_max_scs += MAX_SCS_INCREMENT;
  1164. X
  1165. X    ++num_reallocs;
  1166. X
  1167. X    scset = reallocate_integer_array( scset, current_max_scs );
  1168. X    scbol = reallocate_integer_array( scbol, current_max_scs );
  1169. X    scxclu = reallocate_integer_array( scxclu, current_max_scs );
  1170. X    sceof = reallocate_integer_array( sceof, current_max_scs );
  1171. X    scname = reallocate_char_ptr_array( scname, current_max_scs );
  1172. X    actvsc = reallocate_integer_array( actvsc, current_max_scs );
  1173. X    }
  1174. X
  1175. X    scname[lastsc] = copy_string( str );
  1176. X
  1177. X    if ( addsym( scname[lastsc], (char *) 0, lastsc,
  1178. X         sctbl, START_COND_HASH_SIZE ) )
  1179. X    format_pinpoint_message( "start condition %s declared twice", str );
  1180. X
  1181. X    scset[lastsc] = mkstate( SYM_EPSILON );
  1182. X    scbol[lastsc] = mkstate( SYM_EPSILON );
  1183. X    scxclu[lastsc] = xcluflg;
  1184. X    sceof[lastsc] = false;
  1185. X    }
  1186. X
  1187. X
  1188. X/* sclookup - lookup the number associated with a start condition
  1189. X *
  1190. X * synopsis
  1191. X *    char str[], scnum;
  1192. X *    int sclookup;
  1193. X *    scnum/0 = sclookup( str );
  1194. X */
  1195. X
  1196. Xint sclookup( str )
  1197. Xchar str[];
  1198. X
  1199. X    {
  1200. X    return ( findsym( str, sctbl, START_COND_HASH_SIZE )->int_val );
  1201. X    }
  1202. END_OF_FILE
  1203.   if test 7527 -ne `wc -c <'sym.c'`; then
  1204.     echo shar: \"'sym.c'\" unpacked with wrong size!
  1205.   fi
  1206.   # end of 'sym.c'
  1207. fi
  1208. if test -f 'tblcmp.c' -a "${1}" != "-c" ; then 
  1209.   echo shar: Will not clobber existing file \"'tblcmp.c'\"
  1210. else
  1211.   echo shar: Extracting \"'tblcmp.c'\" \(25169 characters\)
  1212.   sed "s/^X//" >'tblcmp.c' <<'END_OF_FILE'
  1213. X/* tblcmp - table compression routines */
  1214. X
  1215. X/*-
  1216. X * Copyright (c) 1990 The Regents of the University of California.
  1217. X * All rights reserved.
  1218. X *
  1219. X * This code is derived from software contributed to Berkeley by
  1220. X * Vern Paxson.
  1221. X * 
  1222. X * The United States Government has rights in this work pursuant
  1223. X * to contract no. DE-AC03-76SF00098 between the United States
  1224. X * Department of Energy and the University of California.
  1225. X *
  1226. X * Redistribution and use in source and binary forms are permitted provided
  1227. X * that: (1) source distributions retain this entire copyright notice and
  1228. X * comment, and (2) distributions including binaries display the following
  1229. X * acknowledgement:  ``This product includes software developed by the
  1230. X * University of California, Berkeley and its contributors'' in the
  1231. X * documentation or other materials provided with the distribution and in
  1232. X * all advertising materials mentioning features or use of this software.
  1233. X * Neither the name of the University nor the names of its contributors may
  1234. X * be used to endorse or promote products derived from this software without
  1235. X * specific prior written permission.
  1236. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  1237. X * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  1238. X * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  1239. X */
  1240. X
  1241. X#ifndef lint
  1242. Xstatic char rcsid[] =
  1243. X    "@(#) $Header: /usr/fsys/odin/a/vern/flex/RCS/tblcmp.c,v 2.5 90/06/27 23:48:38 vern Exp $ (LBL)";
  1244. X#endif
  1245. X
  1246. X#include "flexdef.h"
  1247. X
  1248. X
  1249. X/* declarations for functions that have forward references */
  1250. X
  1251. Xvoid mkentry PROTO((register int*, int, int, int, int));
  1252. Xvoid mkprot PROTO((int[], int, int));
  1253. Xvoid mktemplate PROTO((int[], int, int));
  1254. Xvoid mv2front PROTO((int));
  1255. Xint tbldiff PROTO((int[], int, int[]));
  1256. X
  1257. X
  1258. X/* bldtbl - build table entries for dfa state
  1259. X *
  1260. X * synopsis
  1261. X *   int state[numecs], statenum, totaltrans, comstate, comfreq;
  1262. X *   bldtbl( state, statenum, totaltrans, comstate, comfreq );
  1263. X *
  1264. X * State is the statenum'th dfa state.  It is indexed by equivalence class and
  1265. X * gives the number of the state to enter for a given equivalence class.
  1266. X * totaltrans is the total number of transitions out of the state.  Comstate
  1267. X * is that state which is the destination of the most transitions out of State.
  1268. X * Comfreq is how many transitions there are out of State to Comstate.
  1269. X *
  1270. X * A note on terminology:
  1271. X *    "protos" are transition tables which have a high probability of
  1272. X * either being redundant (a state processed later will have an identical
  1273. X * transition table) or nearly redundant (a state processed later will have
  1274. X * many of the same out-transitions).  A "most recently used" queue of
  1275. X * protos is kept around with the hope that most states will find a proto
  1276. X * which is similar enough to be usable, and therefore compacting the
  1277. X * output tables.
  1278. X *    "templates" are a special type of proto.  If a transition table is
  1279. X * homogeneous or nearly homogeneous (all transitions go to the same
  1280. X * destination) then the odds are good that future states will also go
  1281. X * to the same destination state on basically the same character set.
  1282. X * These homogeneous states are so common when dealing with large rule
  1283. X * sets that they merit special attention.  If the transition table were
  1284. X * simply made into a proto, then (typically) each subsequent, similar
  1285. X * state will differ from the proto for two out-transitions.  One of these
  1286. X * out-transitions will be that character on which the proto does not go
  1287. X * to the common destination, and one will be that character on which the
  1288. X * state does not go to the common destination.  Templates, on the other
  1289. X * hand, go to the common state on EVERY transition character, and therefore
  1290. X * cost only one difference.
  1291. X */
  1292. X
  1293. Xvoid bldtbl( state, statenum, totaltrans, comstate, comfreq )
  1294. Xint state[], statenum, totaltrans, comstate, comfreq;
  1295. X
  1296. X    {
  1297. X    int extptr, extrct[2][CSIZE + 1];
  1298. X    int mindiff, minprot, i, d;
  1299. X    int checkcom;
  1300. X
  1301. X    /* If extptr is 0 then the first array of extrct holds the result of the
  1302. X     * "best difference" to date, which is those transitions which occur in
  1303. X     * "state" but not in the proto which, to date, has the fewest differences
  1304. X     * between itself and "state".  If extptr is 1 then the second array of
  1305. X     * extrct hold the best difference.  The two arrays are toggled
  1306. X     * between so that the best difference to date can be kept around and
  1307. X     * also a difference just created by checking against a candidate "best"
  1308. X     * proto.
  1309. X     */
  1310. X
  1311. X    extptr = 0;
  1312. X
  1313. X    /* if the state has too few out-transitions, don't bother trying to
  1314. X     * compact its tables
  1315. X     */
  1316. X
  1317. X    if ( (totaltrans * 100) < (numecs * PROTO_SIZE_PERCENTAGE) )
  1318. X    mkentry( state, numecs, statenum, JAMSTATE, totaltrans );
  1319. X
  1320. X    else
  1321. X    {
  1322. X    /* checkcom is true if we should only check "state" against
  1323. X     * protos which have the same "comstate" value
  1324. X     */
  1325. X
  1326. X    checkcom = comfreq * 100 > totaltrans * CHECK_COM_PERCENTAGE;
  1327. X
  1328. X    minprot = firstprot;
  1329. X    mindiff = totaltrans;
  1330. X
  1331. X    if ( checkcom )
  1332. X        {
  1333. X        /* find first proto which has the same "comstate" */
  1334. X        for ( i = firstprot; i != NIL; i = protnext[i] )
  1335. X        if ( protcomst[i] == comstate )
  1336. X            {
  1337. X            minprot = i;
  1338. X            mindiff = tbldiff( state, minprot, extrct[extptr] );
  1339. X            break;
  1340. X            }
  1341. X        }
  1342. X
  1343. X    else
  1344. X        {
  1345. X        /* since we've decided that the most common destination out
  1346. X         * of "state" does not occur with a high enough frequency,
  1347. X         * we set the "comstate" to zero, assuring that if this state
  1348. X         * is entered into the proto list, it will not be considered
  1349. X         * a template.
  1350. X         */
  1351. X        comstate = 0;
  1352. X
  1353. X        if ( firstprot != NIL )
  1354. X        {
  1355. X        minprot = firstprot;
  1356. X        mindiff = tbldiff( state, minprot, extrct[extptr] );
  1357. X        }
  1358. X        }
  1359. X
  1360. X    /* we now have the first interesting proto in "minprot".  If
  1361. X     * it matches within the tolerances set for the first proto,
  1362. X     * we don't want to bother scanning the rest of the proto list
  1363. X     * to see if we have any other reasonable matches.
  1364. X     */
  1365. X
  1366. X    if ( mindiff * 100 > totaltrans * FIRST_MATCH_DIFF_PERCENTAGE )
  1367. X        { /* not a good enough match.  Scan the rest of the protos */
  1368. X        for ( i = minprot; i != NIL; i = protnext[i] )
  1369. X        {
  1370. X        d = tbldiff( state, i, extrct[1 - extptr] );
  1371. X        if ( d < mindiff )
  1372. X            {
  1373. X            extptr = 1 - extptr;
  1374. X            mindiff = d;
  1375. X            minprot = i;
  1376. X            }
  1377. X        }
  1378. X        }
  1379. X
  1380. X    /* check if the proto we've decided on as our best bet is close
  1381. X     * enough to the state we want to match to be usable
  1382. X     */
  1383. X
  1384. X    if ( mindiff * 100 > totaltrans * ACCEPTABLE_DIFF_PERCENTAGE )
  1385. X        {
  1386. X        /* no good.  If the state is homogeneous enough, we make a
  1387. X         * template out of it.  Otherwise, we make a proto.
  1388. X         */
  1389. X
  1390. X        if ( comfreq * 100 >= totaltrans * TEMPLATE_SAME_PERCENTAGE )
  1391. X        mktemplate( state, statenum, comstate );
  1392. X
  1393. X        else
  1394. X        {
  1395. X        mkprot( state, statenum, comstate );
  1396. X        mkentry( state, numecs, statenum, JAMSTATE, totaltrans );
  1397. X        }
  1398. X        }
  1399. X
  1400. X    else
  1401. X        { /* use the proto */
  1402. X        mkentry( extrct[extptr], numecs, statenum,
  1403. X             prottbl[minprot], mindiff );
  1404. X
  1405. X        /* if this state was sufficiently different from the proto
  1406. X         * we built it from, make it, too, a proto
  1407. X         */
  1408. X
  1409. X        if ( mindiff * 100 >= totaltrans * NEW_PROTO_DIFF_PERCENTAGE )
  1410. X        mkprot( state, statenum, comstate );
  1411. X
  1412. X        /* since mkprot added a new proto to the proto queue, it's possible
  1413. X         * that "minprot" is no longer on the proto queue (if it happened
  1414. X         * to have been the last entry, it would have been bumped off).
  1415. X         * If it's not there, then the new proto took its physical place
  1416. X         * (though logically the new proto is at the beginning of the
  1417. X         * queue), so in that case the following call will do nothing.
  1418. X         */
  1419. X
  1420. X        mv2front( minprot );
  1421. X        }
  1422. X    }
  1423. X    }
  1424. X
  1425. X
  1426. X/* cmptmps - compress template table entries
  1427. X *
  1428. X * synopsis
  1429. X *    cmptmps();
  1430. X *
  1431. X *  template tables are compressed by using the 'template equivalence
  1432. X *  classes', which are collections of transition character equivalence
  1433. X *  classes which always appear together in templates - really meta-equivalence
  1434. X *  classes.  until this point, the tables for templates have been stored
  1435. X *  up at the top end of the nxt array; they will now be compressed and have
  1436. X *  table entries made for them.
  1437. X */
  1438. X
  1439. Xvoid cmptmps()
  1440. X
  1441. X    {
  1442. X    int tmpstorage[CSIZE + 1];
  1443. X    register int *tmp = tmpstorage, i, j;
  1444. X    int totaltrans, trans;
  1445. X
  1446. X    peakpairs = numtemps * numecs + tblend;
  1447. X
  1448. X    if ( usemecs )
  1449. X    {
  1450. X    /* create equivalence classes base on data gathered on template
  1451. X     * transitions
  1452. X     */
  1453. X
  1454. X    nummecs = cre8ecs( tecfwd, tecbck, numecs );
  1455. X    }
  1456. X    
  1457. X    else
  1458. X    nummecs = numecs;
  1459. X
  1460. X    if ( lastdfa + numtemps + 1 >= current_max_dfas )
  1461. X    increase_max_dfas();
  1462. X
  1463. X    /* loop through each template */
  1464. X
  1465. X    for ( i = 1; i <= numtemps; ++i )
  1466. X    {
  1467. X    totaltrans = 0;    /* number of non-jam transitions out of this template */
  1468. X
  1469. X    for ( j = 1; j <= numecs; ++j )
  1470. X        {
  1471. X        trans = tnxt[numecs * i + j];
  1472. X
  1473. X        if ( usemecs )
  1474. X        {
  1475. X        /* the absolute value of tecbck is the meta-equivalence class
  1476. X         * of a given equivalence class, as set up by cre8ecs
  1477. X         */
  1478. X        if ( tecbck[j] > 0 )
  1479. X            {
  1480. X            tmp[tecbck[j]] = trans;
  1481. X
  1482. X            if ( trans > 0 )
  1483. X            ++totaltrans;
  1484. X            }
  1485. X        }
  1486. X
  1487. X        else
  1488. X        {
  1489. X        tmp[j] = trans;
  1490. X
  1491. X        if ( trans > 0 )
  1492. X            ++totaltrans;
  1493. X        }
  1494. X        }
  1495. X
  1496. X    /* it is assumed (in a rather subtle way) in the skeleton that
  1497. X     * if we're using meta-equivalence classes, the def[] entry for
  1498. X     * all templates is the jam template, i.e., templates never default
  1499. X     * to other non-jam table entries (e.g., another template)
  1500. X     */
  1501. X
  1502. X    /* leave room for the jam-state after the last real state */
  1503. X    mkentry( tmp, nummecs, lastdfa + i + 1, JAMSTATE, totaltrans );
  1504. X    }
  1505. X    }
  1506. X
  1507. X
  1508. X
  1509. X/* expand_nxt_chk - expand the next check arrays */
  1510. X
  1511. Xvoid expand_nxt_chk()
  1512. X
  1513. X    {
  1514. X    register int old_max = current_max_xpairs;
  1515. X
  1516. X    current_max_xpairs += MAX_XPAIRS_INCREMENT;
  1517. X
  1518. X    ++num_reallocs;
  1519. X
  1520. X    nxt = reallocate_integer_array( nxt, current_max_xpairs );
  1521. X    chk = reallocate_integer_array( chk, current_max_xpairs );
  1522. X
  1523. X    bzero( (char *) (chk + old_max),
  1524. X       MAX_XPAIRS_INCREMENT * sizeof( int ) / sizeof( char ) );
  1525. X    }
  1526. X
  1527. X
  1528. X/* find_table_space - finds a space in the table for a state to be placed
  1529. X *
  1530. X * synopsis
  1531. X *     int *state, numtrans, block_start;
  1532. X *     int find_table_space();
  1533. X *
  1534. X *     block_start = find_table_space( state, numtrans );
  1535. X *
  1536. X * State is the state to be added to the full speed transition table.
  1537. X * Numtrans is the number of out-transitions for the state.
  1538. X *
  1539. X * find_table_space() returns the position of the start of the first block (in
  1540. X * chk) able to accommodate the state
  1541. X *
  1542. X * In determining if a state will or will not fit, find_table_space() must take
  1543. X * into account the fact that an end-of-buffer state will be added at [0],
  1544. X * and an action number will be added in [-1].
  1545. X */
  1546. X
  1547. Xint find_table_space( state, numtrans )
  1548. Xint *state, numtrans;
  1549. X    
  1550. X    {
  1551. X    /* firstfree is the position of the first possible occurrence of two
  1552. X     * consecutive unused records in the chk and nxt arrays
  1553. X     */
  1554. X    register int i;
  1555. X    register int *state_ptr, *chk_ptr;
  1556. X    register int *ptr_to_last_entry_in_state;
  1557. X
  1558. X    /* if there are too many out-transitions, put the state at the end of
  1559. X     * nxt and chk
  1560. X     */
  1561. X    if ( numtrans > MAX_XTIONS_FULL_INTERIOR_FIT )
  1562. X    {
  1563. X    /* if table is empty, return the first available spot in chk/nxt,
  1564. X     * which should be 1
  1565. X     */
  1566. X    if ( tblend < 2 )
  1567. X        return ( 1 );
  1568. X
  1569. X    i = tblend - numecs;    /* start searching for table space near the
  1570. X                 * end of chk/nxt arrays
  1571. X                 */
  1572. X    }
  1573. X
  1574. X    else
  1575. X    i = firstfree;        /* start searching for table space from the
  1576. X                 * beginning (skipping only the elements
  1577. X                 * which will definitely not hold the new
  1578. X                 * state)
  1579. X                 */
  1580. X
  1581. X    while ( 1 )        /* loops until a space is found */
  1582. X    {
  1583. X    if ( i + numecs > current_max_xpairs )
  1584. X        expand_nxt_chk();
  1585. X
  1586. X    /* loops until space for end-of-buffer and action number are found */
  1587. X    while ( 1 )
  1588. X        {
  1589. X        if ( chk[i - 1] == 0 )    /* check for action number space */
  1590. X        {
  1591. X        if ( chk[i] == 0 )    /* check for end-of-buffer space */
  1592. X            break;
  1593. X
  1594. X        else
  1595. X            i += 2;    /* since i != 0, there is no use checking to
  1596. X                 * see if (++i) - 1 == 0, because that's the
  1597. X                 * same as i == 0, so we skip a space
  1598. X                 */
  1599. X        }
  1600. X
  1601. X        else
  1602. X        ++i;
  1603. X
  1604. X        if ( i + numecs > current_max_xpairs )
  1605. X        expand_nxt_chk();
  1606. X        }
  1607. X
  1608. X    /* if we started search from the beginning, store the new firstfree for
  1609. X     * the next call of find_table_space()
  1610. X     */
  1611. X    if ( numtrans <= MAX_XTIONS_FULL_INTERIOR_FIT )
  1612. X        firstfree = i + 1;
  1613. X
  1614. X    /* check to see if all elements in chk (and therefore nxt) that are
  1615. X     * needed for the new state have not yet been taken
  1616. X     */
  1617. X
  1618. X    state_ptr = &state[1];
  1619. X    ptr_to_last_entry_in_state = &chk[i + numecs + 1];
  1620. X
  1621. X    for ( chk_ptr = &chk[i + 1]; chk_ptr != ptr_to_last_entry_in_state;
  1622. X          ++chk_ptr )
  1623. X        if ( *(state_ptr++) != 0 && *chk_ptr != 0 )
  1624. X        break;
  1625. X
  1626. X    if ( chk_ptr == ptr_to_last_entry_in_state )
  1627. X        return ( i );
  1628. X
  1629. X    else
  1630. X        ++i;
  1631. X    }
  1632. X    }
  1633. X
  1634. X
  1635. X/* inittbl - initialize transition tables
  1636. X *
  1637. X * synopsis
  1638. X *   inittbl();
  1639. X *
  1640. X * Initializes "firstfree" to be one beyond the end of the table.  Initializes
  1641. X * all "chk" entries to be zero.  Note that templates are built in their
  1642. X * own tbase/tdef tables.  They are shifted down to be contiguous
  1643. X * with the non-template entries during table generation.
  1644. X */
  1645. Xvoid inittbl()
  1646. X
  1647. X    {
  1648. X    register int i;
  1649. X
  1650. X    bzero( (char *) chk, current_max_xpairs * sizeof( int ) / sizeof( char ) );
  1651. X
  1652. X    tblend = 0;
  1653. X    firstfree = tblend + 1;
  1654. X    numtemps = 0;
  1655. X
  1656. X    if ( usemecs )
  1657. X    {
  1658. X    /* set up doubly-linked meta-equivalence classes
  1659. X     * these are sets of equivalence classes which all have identical
  1660. X     * transitions out of TEMPLATES
  1661. X     */
  1662. X
  1663. X    tecbck[1] = NIL;
  1664. X
  1665. X    for ( i = 2; i <= numecs; ++i )
  1666. X        {
  1667. X        tecbck[i] = i - 1;
  1668. X        tecfwd[i - 1] = i;
  1669. X        }
  1670. X
  1671. X    tecfwd[numecs] = NIL;
  1672. X    }
  1673. X    }
  1674. X
  1675. X
  1676. X/* mkdeftbl - make the default, "jam" table entries
  1677. X *
  1678. X * synopsis
  1679. X *   mkdeftbl();
  1680. X */
  1681. X
  1682. Xvoid mkdeftbl()
  1683. X
  1684. X    {
  1685. X    int i;
  1686. X
  1687. X    jamstate = lastdfa + 1;
  1688. X
  1689. X    ++tblend; /* room for transition on end-of-buffer character */
  1690. X
  1691. X    if ( tblend + numecs > current_max_xpairs )
  1692. X    expand_nxt_chk();
  1693. X
  1694. X    /* add in default end-of-buffer transition */
  1695. X    nxt[tblend] = end_of_buffer_state;
  1696. X    chk[tblend] = jamstate;
  1697. X
  1698. X    for ( i = 1; i <= numecs; ++i )
  1699. X    {
  1700. X    nxt[tblend + i] = 0;
  1701. X    chk[tblend + i] = jamstate;
  1702. X    }
  1703. X
  1704. X    jambase = tblend;
  1705. X
  1706. X    base[jamstate] = jambase;
  1707. X    def[jamstate] = 0;
  1708. X
  1709. X    tblend += numecs;
  1710. X    ++numtemps;
  1711. X    }
  1712. X
  1713. X
  1714. X/* mkentry - create base/def and nxt/chk entries for transition array
  1715. X *
  1716. X * synopsis
  1717. X *   int state[numchars + 1], numchars, statenum, deflink, totaltrans;
  1718. X *   mkentry( state, numchars, statenum, deflink, totaltrans );
  1719. X *
  1720. X * "state" is a transition array "numchars" characters in size, "statenum"
  1721. X * is the offset to be used into the base/def tables, and "deflink" is the
  1722. X * entry to put in the "def" table entry.  If "deflink" is equal to
  1723. X * "JAMSTATE", then no attempt will be made to fit zero entries of "state"
  1724. X * (i.e., jam entries) into the table.  It is assumed that by linking to
  1725. X * "JAMSTATE" they will be taken care of.  In any case, entries in "state"
  1726. X * marking transitions to "SAME_TRANS" are treated as though they will be
  1727. X * taken care of by whereever "deflink" points.  "totaltrans" is the total
  1728. X * number of transitions out of the state.  If it is below a certain threshold,
  1729. X * the tables are searched for an interior spot that will accommodate the
  1730. X * state array.
  1731. X */
  1732. X
  1733. Xvoid mkentry( state, numchars, statenum, deflink, totaltrans )
  1734. Xregister int *state;
  1735. Xint numchars, statenum, deflink, totaltrans;
  1736. X
  1737. X    {
  1738. X    register int minec, maxec, i, baseaddr;
  1739. X    int tblbase, tbllast;
  1740. X
  1741. X    if ( totaltrans == 0 )
  1742. X    { /* there are no out-transitions */
  1743. X    if ( deflink == JAMSTATE )
  1744. X        base[statenum] = JAMSTATE;
  1745. X    else
  1746. X        base[statenum] = 0;
  1747. X
  1748. X    def[statenum] = deflink;
  1749. X    return;
  1750. X    }
  1751. X
  1752. X    for ( minec = 1; minec <= numchars; ++minec )
  1753. X    {
  1754. X    if ( state[minec] != SAME_TRANS )
  1755. X        if ( state[minec] != 0 || deflink != JAMSTATE )
  1756. X        break;
  1757. X    }
  1758. X
  1759. X    if ( totaltrans == 1 )
  1760. X    {
  1761. X    /* there's only one out-transition.  Save it for later to fill
  1762. X     * in holes in the tables.
  1763. X     */
  1764. X    stack1( statenum, minec, state[minec], deflink );
  1765. X    return;
  1766. X    }
  1767. X
  1768. X    for ( maxec = numchars; maxec > 0; --maxec )
  1769. X    {
  1770. X    if ( state[maxec] != SAME_TRANS )
  1771. X        if ( state[maxec] != 0 || deflink != JAMSTATE )
  1772. X        break;
  1773. X    }
  1774. X
  1775. X    /* Whether we try to fit the state table in the middle of the table
  1776. X     * entries we have already generated, or if we just take the state
  1777. X     * table at the end of the nxt/chk tables, we must make sure that we
  1778. X     * have a valid base address (i.e., non-negative).  Note that not only are
  1779. X     * negative base addresses dangerous at run-time (because indexing the
  1780. X     * next array with one and a low-valued character might generate an
  1781. X     * array-out-of-bounds error message), but at compile-time negative
  1782. X     * base addresses denote TEMPLATES.
  1783. X     */
  1784. X
  1785. X    /* find the first transition of state that we need to worry about. */
  1786. X    if ( totaltrans * 100 <= numchars * INTERIOR_FIT_PERCENTAGE )
  1787. X    { /* attempt to squeeze it into the middle of the tabls */
  1788. X    baseaddr = firstfree;
  1789. X
  1790. X    while ( baseaddr < minec )
  1791. X        {
  1792. X        /* using baseaddr would result in a negative base address below
  1793. X         * find the next free slot
  1794. X         */
  1795. X        for ( ++baseaddr; chk[baseaddr] != 0; ++baseaddr )
  1796. X        ;
  1797. X        }
  1798. X
  1799. X    if ( baseaddr + maxec - minec >= current_max_xpairs )
  1800. X        expand_nxt_chk();
  1801. X
  1802. X    for ( i = minec; i <= maxec; ++i )
  1803. X        if ( state[i] != SAME_TRANS )
  1804. X        if ( state[i] != 0 || deflink != JAMSTATE )
  1805. X            if ( chk[baseaddr + i - minec] != 0 )
  1806. X            { /* baseaddr unsuitable - find another */
  1807. X            for ( ++baseaddr;
  1808. X                  baseaddr < current_max_xpairs &&
  1809. X                  chk[baseaddr] != 0;
  1810. X                  ++baseaddr )
  1811. X                ;
  1812. X
  1813. X            if ( baseaddr + maxec - minec >= current_max_xpairs )
  1814. X                expand_nxt_chk();
  1815. X
  1816. X            /* reset the loop counter so we'll start all
  1817. X             * over again next time it's incremented
  1818. X             */
  1819. X
  1820. X            i = minec - 1;
  1821. X            }
  1822. X    }
  1823. X
  1824. X    else
  1825. X    {
  1826. X    /* ensure that the base address we eventually generate is
  1827. X     * non-negative
  1828. X     */
  1829. X    baseaddr = max( tblend + 1, minec );
  1830. X    }
  1831. X
  1832. X    tblbase = baseaddr - minec;
  1833. X    tbllast = tblbase + maxec;
  1834. X
  1835. X    if ( tbllast >= current_max_xpairs )
  1836. X    expand_nxt_chk();
  1837. X
  1838. X    base[statenum] = tblbase;
  1839. X    def[statenum] = deflink;
  1840. X
  1841. X    for ( i = minec; i <= maxec; ++i )
  1842. X    if ( state[i] != SAME_TRANS )
  1843. X        if ( state[i] != 0 || deflink != JAMSTATE )
  1844. X        {
  1845. X        nxt[tblbase + i] = state[i];
  1846. X        chk[tblbase + i] = statenum;
  1847. X        }
  1848. X
  1849. X    if ( baseaddr == firstfree )
  1850. X    /* find next free slot in tables */
  1851. X    for ( ++firstfree; chk[firstfree] != 0; ++firstfree )
  1852. X        ;
  1853. X
  1854. X    tblend = max( tblend, tbllast );
  1855. X    }
  1856. X
  1857. X
  1858. X/* mk1tbl - create table entries for a state (or state fragment) which
  1859. X *            has only one out-transition
  1860. X *
  1861. X * synopsis
  1862. X *   int state, sym, onenxt, onedef;
  1863. X *   mk1tbl( state, sym, onenxt, onedef );
  1864. X */
  1865. X
  1866. Xvoid mk1tbl( state, sym, onenxt, onedef )
  1867. Xint state, sym, onenxt, onedef;
  1868. X
  1869. X    {
  1870. X    if ( firstfree < sym )
  1871. X    firstfree = sym;
  1872. X
  1873. X    while ( chk[firstfree] != 0 )
  1874. X    if ( ++firstfree >= current_max_xpairs )
  1875. X        expand_nxt_chk();
  1876. X
  1877. X    base[state] = firstfree - sym;
  1878. X    def[state] = onedef;
  1879. X    chk[firstfree] = state;
  1880. X    nxt[firstfree] = onenxt;
  1881. X
  1882. X    if ( firstfree > tblend )
  1883. X    {
  1884. X    tblend = firstfree++;
  1885. X
  1886. X    if ( firstfree >= current_max_xpairs )
  1887. X        expand_nxt_chk();
  1888. X    }
  1889. X    }
  1890. X
  1891. X
  1892. X/* mkprot - create new proto entry
  1893. X *
  1894. X * synopsis
  1895. X *   int state[], statenum, comstate;
  1896. X *   mkprot( state, statenum, comstate );
  1897. X */
  1898. X
  1899. Xvoid mkprot( state, statenum, comstate )
  1900. Xint state[], statenum, comstate;
  1901. X
  1902. X    {
  1903. X    int i, slot, tblbase;
  1904. X
  1905. X    if ( ++numprots >= MSP || numecs * numprots >= PROT_SAVE_SIZE )
  1906. X    {
  1907. X    /* gotta make room for the new proto by dropping last entry in
  1908. X     * the queue
  1909. X     */
  1910. X    slot = lastprot;
  1911. X    lastprot = protprev[lastprot];
  1912. X    protnext[lastprot] = NIL;
  1913. X    }
  1914. X
  1915. X    else
  1916. X    slot = numprots;
  1917. X
  1918. X    protnext[slot] = firstprot;
  1919. X
  1920. X    if ( firstprot != NIL )
  1921. X    protprev[firstprot] = slot;
  1922. X
  1923. X    firstprot = slot;
  1924. X    prottbl[slot] = statenum;
  1925. X    protcomst[slot] = comstate;
  1926. X
  1927. X    /* copy state into save area so it can be compared with rapidly */
  1928. X    tblbase = numecs * (slot - 1);
  1929. X
  1930. X    for ( i = 1; i <= numecs; ++i )
  1931. X    protsave[tblbase + i] = state[i];
  1932. X    }
  1933. X
  1934. X
  1935. X/* mktemplate - create a template entry based on a state, and connect the state
  1936. X *              to it
  1937. X *
  1938. X * synopsis
  1939. X *   int state[], statenum, comstate, totaltrans;
  1940. X *   mktemplate( state, statenum, comstate, totaltrans );
  1941. X */
  1942. X
  1943. Xvoid mktemplate( state, statenum, comstate )
  1944. Xint state[], statenum, comstate;
  1945. X
  1946. X    {
  1947. X    int i, numdiff, tmpbase, tmp[CSIZE + 1];
  1948. X    Char transset[CSIZE + 1];
  1949. X    int tsptr;
  1950. X
  1951. X    ++numtemps;
  1952. X
  1953. X    tsptr = 0;
  1954. X
  1955. X    /* calculate where we will temporarily store the transition table
  1956. X     * of the template in the tnxt[] array.  The final transition table
  1957. X     * gets created by cmptmps()
  1958. X     */
  1959. X
  1960. X    tmpbase = numtemps * numecs;
  1961. X
  1962. X    if ( tmpbase + numecs >= current_max_template_xpairs )
  1963. X    {
  1964. X    current_max_template_xpairs += MAX_TEMPLATE_XPAIRS_INCREMENT;
  1965. X
  1966. X    ++num_reallocs;
  1967. X
  1968. X    tnxt = reallocate_integer_array( tnxt, current_max_template_xpairs );
  1969. X    }
  1970. X
  1971. X    for ( i = 1; i <= numecs; ++i )
  1972. X    if ( state[i] == 0 )
  1973. X        tnxt[tmpbase + i] = 0;
  1974. X    else
  1975. X        {
  1976. X        transset[tsptr++] = i;
  1977. X        tnxt[tmpbase + i] = comstate;
  1978. X        }
  1979. X
  1980. X    if ( usemecs )
  1981. X    mkeccl( transset, tsptr, tecfwd, tecbck, numecs, 0 );
  1982. X
  1983. X    mkprot( tnxt + tmpbase, -numtemps, comstate );
  1984. X
  1985. X    /* we rely on the fact that mkprot adds things to the beginning
  1986. X     * of the proto queue
  1987. X     */
  1988. X
  1989. X    numdiff = tbldiff( state, firstprot, tmp );
  1990. X    mkentry( tmp, numecs, statenum, -numtemps, numdiff );
  1991. X    }
  1992. X
  1993. X
  1994. X/* mv2front - move proto queue element to front of queue
  1995. X *
  1996. X * synopsis
  1997. X *   int qelm;
  1998. X *   mv2front( qelm );
  1999. X */
  2000. X
  2001. Xvoid mv2front( qelm )
  2002. Xint qelm;
  2003. X
  2004. X    {
  2005. X    if ( firstprot != qelm )
  2006. X    {
  2007. X    if ( qelm == lastprot )
  2008. X        lastprot = protprev[lastprot];
  2009. X
  2010. X    protnext[protprev[qelm]] = protnext[qelm];
  2011. X
  2012. X    if ( protnext[qelm] != NIL )
  2013. X        protprev[protnext[qelm]] = protprev[qelm];
  2014. X
  2015. X    protprev[qelm] = NIL;
  2016. X    protnext[qelm] = firstprot;
  2017. X    protprev[firstprot] = qelm;
  2018. X    firstprot = qelm;
  2019. X    }
  2020. X    }
  2021. X
  2022. X
  2023. X/* place_state - place a state into full speed transition table
  2024. X *
  2025. X * synopsis
  2026. X *     int *state, statenum, transnum;
  2027. X *     place_state( state, statenum, transnum );
  2028. X *
  2029. X * State is the statenum'th state.  It is indexed by equivalence class and
  2030. X * gives the number of the state to enter for a given equivalence class.
  2031. X * Transnum is the number of out-transitions for the state.
  2032. X */
  2033. X
  2034. Xvoid place_state( state, statenum, transnum )
  2035. Xint *state, statenum, transnum;
  2036. X
  2037. X    {
  2038. X    register int i;
  2039. X    register int *state_ptr;
  2040. X    int position = find_table_space( state, transnum );
  2041. X
  2042. X    /* base is the table of start positions */
  2043. X    base[statenum] = position;
  2044. X
  2045. X    /* put in action number marker; this non-zero number makes sure that
  2046. X     * find_table_space() knows that this position in chk/nxt is taken
  2047. X     * and should not be used for another accepting number in another state
  2048. X     */
  2049. X    chk[position - 1] = 1;
  2050. X
  2051. X    /* put in end-of-buffer marker; this is for the same purposes as above */
  2052. X    chk[position] = 1;
  2053. X
  2054. X    /* place the state into chk and nxt */
  2055. X    state_ptr = &state[1];
  2056. X
  2057. X    for ( i = 1; i <= numecs; ++i, ++state_ptr )
  2058. X    if ( *state_ptr != 0 )
  2059. X        {
  2060. X        chk[position + i] = i;
  2061. X        nxt[position + i] = *state_ptr;
  2062. X        }
  2063. X
  2064. X    if ( position + numecs > tblend )
  2065. X    tblend = position + numecs;
  2066. X    }
  2067. X
  2068. X
  2069. X/* stack1 - save states with only one out-transition to be processed later
  2070. X *
  2071. X * synopsis
  2072. X *   int statenum, sym, nextstate, deflink;
  2073. X *   stack1( statenum, sym, nextstate, deflink );
  2074. X *
  2075. X * if there's room for another state one the "one-transition" stack, the
  2076. X * state is pushed onto it, to be processed later by mk1tbl.  If there's
  2077. X * no room, we process the sucker right now.
  2078. X */
  2079. X
  2080. Xvoid stack1( statenum, sym, nextstate, deflink )
  2081. Xint statenum, sym, nextstate, deflink;
  2082. X
  2083. X    {
  2084. X    if ( onesp >= ONE_STACK_SIZE - 1 )
  2085. X    mk1tbl( statenum, sym, nextstate, deflink );
  2086. X
  2087. X    else
  2088. X    {
  2089. X    ++onesp;
  2090. X    onestate[onesp] = statenum;
  2091. X    onesym[onesp] = sym;
  2092. X    onenext[onesp] = nextstate;
  2093. X    onedef[onesp] = deflink;
  2094. X    }
  2095. X    }
  2096. X
  2097. X
  2098. X/* tbldiff - compute differences between two state tables
  2099. X *
  2100. X * synopsis
  2101. X *   int state[], pr, ext[];
  2102. X *   int tbldiff, numdifferences;
  2103. X *   numdifferences = tbldiff( state, pr, ext )
  2104. X *
  2105. X * "state" is the state array which is to be extracted from the pr'th
  2106. X * proto.  "pr" is both the number of the proto we are extracting from
  2107. X * and an index into the save area where we can find the proto's complete
  2108. X * state table.  Each entry in "state" which differs from the corresponding
  2109. X * entry of "pr" will appear in "ext".
  2110. X * Entries which are the same in both "state" and "pr" will be marked
  2111. X * as transitions to "SAME_TRANS" in "ext".  The total number of differences
  2112. X * between "state" and "pr" is returned as function value.  Note that this
  2113. X * number is "numecs" minus the number of "SAME_TRANS" entries in "ext".
  2114. X */
  2115. X
  2116. Xint tbldiff( state, pr, ext )
  2117. Xint state[], pr, ext[];
  2118. X
  2119. X    {
  2120. X    register int i, *sp = state, *ep = ext, *protp;
  2121. X    register int numdiff = 0;
  2122. X
  2123. X    protp = &protsave[numecs * (pr - 1)];
  2124. X
  2125. X    for ( i = numecs; i > 0; --i )
  2126. X    {
  2127. X    if ( *++protp == *++sp )
  2128. X        *++ep = SAME_TRANS;
  2129. X    else
  2130. X        {
  2131. X        *++ep = *sp;
  2132. X        ++numdiff;
  2133. X        }
  2134. X    }
  2135. X
  2136. X    return ( numdiff );
  2137. X    }
  2138. END_OF_FILE
  2139.   if test 25169 -ne `wc -c <'tblcmp.c'`; then
  2140.     echo shar: \"'tblcmp.c'\" unpacked with wrong size!
  2141.   fi
  2142.   # end of 'tblcmp.c'
  2143. fi
  2144. echo shar: End of archive 7 \(of 10\).
  2145. cp /dev/null ark7isdone
  2146. MISSING=""
  2147. for I in 1 2 3 4 5 6 7 8 9 10 ; do
  2148.     if test ! -f ark${I}isdone ; then
  2149.     MISSING="${MISSING} ${I}"
  2150.     fi
  2151. done
  2152. if test "${MISSING}" = "" ; then
  2153.     echo You have unpacked all 10 archives.
  2154.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2155. else
  2156.     echo You still must unpack the following archives:
  2157.     echo "        " ${MISSING}
  2158. fi
  2159. exit 0
  2160. exit 0 # Just in case...
  2161.